package tuanda.soict.firstsun.DataPackage;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Random;

/**
 * @author tuanda_soict_hut
 * @version 0.0.3
 * @since 7-9-2012
 */
public enum ArmyDataSet implements CommonConstants, AbilityList {

	// RANK = MINATK + MAXATK + DEF*2 + MOV*5 + RAN*10 + TYPE - GOLD/10
	// SEA_TYPE: +10
	// LAND_TYPE: +15
	// AIR_TYPE: +30
	// (MINATK , MAXATK , DEF , MOV , RAN , TYPE)
	//
	// HUMAN//
	//
	SOLDIER(0, "SOLDIER", 130, 40, 45, 5, 5, 1, LAND_TYPE, 150, RUN, NO_SKILL,
			NO_SKILL, NO_SKILL),
	//
	WIZARD(1, "WIZARD", 130, 35, 35, 0, 4, 2, LAND_TYPE + SEA_TYPE, 150,
			LIGHTNING, FIREBALL, EARTHQUAKE, BLIZZARD),
	//
	ARCHER(2, "ARCHER", 130, 35, 45, 5, 5, 2, LAND_TYPE, 200, CONCENTRATE,
			BURN, NO_SKILL, NO_SKILL),
	//
	CLERIC(3, "CLERIC", 135, 35, 40, 5, 4, 2, LAND_TYPE, 200, BLESS, CURE,
			HASTE, PRAY),
	//
	GUARDIAN(4, "GUARDIAN", 135, 40, 45, 15, 4, 1, LAND_TYPE, 250, DEFEND,
			NO_SKILL, NO_SKILL, NO_SKILL),
	//
	GRYPHON(5, "GRYPHON", 140, 40, 50, 5, 6, 1, AIR_TYPE, 300, SLEEP, POISON,
			NO_SKILL, NO_SKILL),
	//
	KNIGHT(6, "KNIGHT", 150, 45, 55, 15, 6, 1, LAND_TYPE, 350, CHARGE,
			NO_SKILL, NO_SKILL, NO_SKILL),
	//
	ANGEL(7, "ANGEL", 160, 60, 60, 10, 7, 1, AIR_TYPE, 500, FIRST_AID,
			EPIPHANY, MERCY, RESURRECT),
	//
	BATTLESHIP(8, "BATTLE SHIP", 155, 50, 55, 10, 6, 3, SEA_TYPE, 400, CHARGE,
			RUN, NO_SKILL, NO_SKILL),
	//
	CRUISER(9, "CRUISER", 145, 40, 50, 5, 9, 2, SEA_TYPE, 300, CHARGE,
			RUN, NO_SKILL, NO_SKILL),
	//
	// ELF//
	//
	WISP(32, "WISP", 130, 25, 25, 0, 2, 1, AIR_TYPE, 100, TRANSFORM, NO_SKILL,
			NO_SKILL, NO_SKILL),
	//
	HUNTER(33, "HUNTER", 130, 35, 40, 10, 6, 1, LAND_TYPE, 200, RUN, DEFEND,
			CONCENTRATE, CHARGE),
	//
	SAGE(34, "SAGE", 140, 35, 45, 5, 7, 2, LAND_TYPE + SEA_TYPE, 300, SCHOLAR,
			NO_SKILL, NO_SKILL, NO_SKILL),
	//
	PHOENIX(35, "PHOENIX", 150, 40, 50, 10, 8, 1, AIR_TYPE, 400, BURN,
			NO_SKILL, SLEEP, NO_SKILL),
	//
	LEVIATHAN(36, "LEVIATHAN", 145, 40, 50, 0, 8, 3, SEA_TYPE, 350, POISON,
			FIRST_AID, NO_SKILL, NO_SKILL),
	//
	SIREN(37, "PHOENIX", 135, 40, 50, 10, 8, 1, SEA_TYPE, 350, SLOW, CURSE,
			NO_SKILL, NO_SKILL),
	//
	WATER_ELEMENTAL(38, "WATER_ELEMENTAL", 135, 30, 45, 10, 6, 1, LAND_TYPE
			+ SEA_TYPE, 250, RETRANSFORM, BLIZZARD, PROMOTE, NO_SKILL),
	//
	FIRE_ELEMENTAL(39, "FIRE_ELEMENTAL", 135, 35, 65, 0, 7, 1, LAND_TYPE, 250,
			RETRANSFORM, FIREBALL, PROMOTE, NO_SKILL),
	//
	AIR_ELEMENTAL(40, "AIR_ELEMENTAL", 135, 20, 45, 5, 7, 2, AIR_TYPE, 250,
			RETRANSFORM, LIGHTNING, PROMOTE, NO_SKILL),
	//
	EARTH_ELEMENTAL(41, "EARTH_ELEMENTAL", 135, 35, 40, 20, 4, 1, LAND_TYPE,
			250, RETRANSFORM, EARTHQUAKE, PROMOTE, NO_SKILL),
	//
	LIGHT_ELEMENTAL(42, "LIGHT_ELEMENTAL", 135, 30, 35, 10, 6, 2, AIR_TYPE,
			300, RETRANSFORM, RESURRECT, PROMOTE, NO_SKILL),
	//
	DARK_ELEMENTAL(43, "DARK_ELEMENTAL", 135, 40, 45, 0, 6, 2, AIR_TYPE, 300,
			RETRANSFORM, SLEEP, PROMOTE, NO_SKILL),
	//
	ICE_ELEMENTAL(44, "ICE_ELEMENTAL", 145, 35, 50, 10, 6, 1, LAND_TYPE
			+ SEA_TYPE, 300, CONCENTRATE, BLIZZARD, NO_SKILL, NO_SKILL),
	//
	LAVA_ELEMENTAL(45, "LAVA_ELEMENTAL", 145, 40, 70, 0, 7, 1, LAND_TYPE, 300,
			CHARGE, FIREBALL, NO_SKILL, NO_SKILL),
	//
	STORM_ELEMENTAL(46, "STORM_ELEMENTAL", 145, 25, 50, 5, 7, 2, AIR_TYPE, 300,
			RUN, LIGHTNING, NO_SKILL, NO_SKILL),
	//
	MAGMA_ELEMENTAL(47, "MAGMA_ELEMENTAL", 145, 40, 45, 20, 4, 1, LAND_TYPE,
			300, DEFEND, EARTHQUAKE, NO_SKILL, NO_SKILL),
	//
	GOD_ELEMENTAL(48, "GOD_ELEMENTAL", 145, 35, 40, 10, 6, 2, AIR_TYPE, 350,
			FIRST_AID, RESURRECT, SECOND_CHANCE, NO_SKILL),
	//
	EVIL_ELEMENTAL(49, "EVIL_ELEMENTAL", 145, 45, 50, 0, 6, 2, AIR_TYPE, 350,
			CURSE, SLEEP, NO_SKILL, NO_SKILL);
	//
	private final int ID;
	private final String name;
	private final int rank;
	private final int minAttack;
	private final int maxAttack;
	private final int defense;
	private final int movement;
	private final int attackRange;
	private final int type;
	private final int goldRequire;
	private final int skill_1;
	private final int skill_2;
	private final int skill_3;
	private final int skill_4;

	private ArmyDataSet(int id, String nam, int ran, int minAtk, int maxAtk,
			int def, int mov, int range, int typ, int gold, int s_1, int s_2,
			int s_3, int s_4) {
		ID = id;
		name = nam;
		rank = ran;
		minAttack = minAtk;
		maxAttack = maxAtk;
		defense = def;
		movement = mov;
		attackRange = range;
		type = typ;
		goldRequire = gold;
		skill_1 = s_1;
		skill_2 = s_2;
		skill_3 = s_3;
		skill_4 = s_4;
	}

	public final int getID() {
		return this.ID;
	}

	public final int getDataID() {
		return this.ID % MAX_NUMBER_UNIT;
	}

	public final String getName() {
		return this.name;
	}

	public final int getType() {
		return this.type;
	}

	public final int getGoldRequire() {
		return this.goldRequire;
	}

	public final int getRank() {
		return this.rank;
	}

	public final int getAttackRange() {
		return this.attackRange;
	}

	public final int getMinAttack() {
		return this.minAttack;
	}

	public final int getMaxAttack() {
		return this.maxAttack;
	}

	public final int getMovement() {
		return this.movement;
	}

	public final int getDefense() {
		return this.defense;
	}

	public final AbilityDataSet[] getSkill() {
		AbilityDataSet abilityDataSet = AbilityDataSet.BLESS;
		AbilityDataSet[] temp = { abilityDataSet.getAbility(skill_1),
				abilityDataSet.getAbility(skill_2),
				abilityDataSet.getAbility(skill_3),
				abilityDataSet.getAbility(skill_4) };
		return temp;
	}

	public final AbilityDataSet getSkill(int index) {
		AbilityDataSet abilityDataSet = AbilityDataSet.BLESS;
		if (index > -1 && index < MAX_NUMBER_SKILL) {
			switch (index) {
			case 0:
				return abilityDataSet.getAbility(skill_1);
			case 1:
				return abilityDataSet.getAbility(skill_2);
			case 2:
				return abilityDataSet.getAbility(skill_3);
			case 3:
				return abilityDataSet.getAbility(skill_4);
			default:
				return abilityDataSet.getAbility(NO_SKILL);
			}
		}
		return abilityDataSet.getAbility(NO_SKILL);
	}

	public final ArmyDataSet getArmyData(int id) {
		for (ArmyDataSet army : ArmyDataSet.values()) {
			if (army.getID() == id) {
				return army;
			}
		}
		return ArmyDataSet.SOLDIER;
	}

	public final int getNumberArmyType(int type) {
		if (type == HUMAN) {
			return 10;
		} else if (type == ELF) {
			return 6;
		} else {
			return INDEX_OUT_OF_BOUND;
		}
	}

	public final ArrayList<ArmyDataSet> getArmyGroup(int type, int producePlace) {
		ArrayList<ArmyDataSet> result = new ArrayList<ArmyDataSet>();
		if (producePlace == LAND_TYPE) {
			switch (type) {
			case HUMAN:
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.SOLDIER,
						ArmyDataSet.ANGEL)) {
					result.add(army);
				}
				return result;
			case ELF:
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.WISP,
						ArmyDataSet.PHOENIX)) {
					result.add(army);
				}
				return result;
			default:
				return null;
			}
		} else if (producePlace == SEA_TYPE) {
			switch (type) {
			case HUMAN:
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.BATTLESHIP,
						ArmyDataSet.CRUISER)) {
					result.add(army);
				}
				return result;
			case ELF:
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.LEVIATHAN,
						ArmyDataSet.SIREN)) {
					result.add(army);
				}
				return result;
			default:
				return null;
			}
		} else {
			return null;
		}
	}

	public final ArmyDataSet findAppropriateArmy(int type, int gold,
			int producePlace) {
		if (producePlace == LAND_TYPE) {
			switch (type) {
			case HUMAN: {
				int i = ArmyDataSet.SOLDIER.getID();
				int j = 0;
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.SOLDIER,
						ArmyDataSet.ANGEL)) {
					if (army.getGoldRequire() > gold) {
						break;
					}
					j++;
				}
				if (j > 0) {
					int k = i + (new Random()).nextInt(j);
					for (ArmyDataSet army : EnumSet.range(ArmyDataSet.SOLDIER,
							ArmyDataSet.ANGEL)) {
						if (army.getID() == k) {
							return army;
						}
					}
					return null;
				} else {
					return null;
				}
			}
			case ELF: {
				int i = ArmyDataSet.HUNTER.getID();
				int j = 0;
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.HUNTER,
						ArmyDataSet.PHOENIX)) {
					if (army.getGoldRequire() > gold) {
						break;
					}
					j++;
				}
				if (j > 0) {
					int k = i + (new Random()).nextInt(j);
					for (ArmyDataSet army : EnumSet.range(ArmyDataSet.HUNTER,
							ArmyDataSet.PHOENIX)) {
						if (army.getID() == k) {
							return army;
						}
					}
					return null;
				} else {
					return null;
				}
			}
			default:
				return null;
			}
		} else if (producePlace == SEA_TYPE) {
			switch (type) {
			case HUMAN: {
				int i = ArmyDataSet.BATTLESHIP.getID();
				int j = 0;
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.BATTLESHIP,
						ArmyDataSet.CRUISER)) {
					if (army.getGoldRequire() > gold) {
						break;
					}
					j++;
				}
				if (j > 0) {
					int k = i + (new Random()).nextInt(j);
					for (ArmyDataSet army : EnumSet.range(
							ArmyDataSet.BATTLESHIP, ArmyDataSet.CRUISER)) {
						if (army.getID() == k) {
							return army;
						}
					}
					return null;
				} else {
					return null;
				}
			}
			case ELF: {
				int i = ArmyDataSet.LEVIATHAN.getID();
				int j = 0;
				for (ArmyDataSet army : EnumSet.range(ArmyDataSet.LEVIATHAN,
						ArmyDataSet.SIREN)) {
					if (army.getGoldRequire() > gold) {
						break;
					}
					j++;
				}
				if (j > 0) {
					int k = i + (new Random()).nextInt(j);
					for (ArmyDataSet army : EnumSet.range(
							ArmyDataSet.LEVIATHAN, ArmyDataSet.SIREN)) {
						if (army.getID() == k) {
							return army;
						}
					}
					return null;
				} else {
					return null;
				}
			}
			default:
				return null;
			}
		} else {
			return null;
		}
	}
}
